#ifndef STATE_MACHINE_HPP
#define STATE_MACHINE_HPP

#include <iostream>
#include <thread>
#include <memory>
#include <unordered_map>
#include <atomic>
#include <chrono>
#include "driver.h"

extern MainWindow *w;
// 定义事件类型
enum class Event {
    START,
    LIMITATION_1,//<--
    LIMITATION_2,//-->
    SCANNED,
    CAPTURE_T,
    CAPTURE_C,
    NONE
};

enum class TRANSFER {
    FORWARD,//<--
    BACKWARD,//-->
    NONE
};

// 定义状态基类
class State {
public:
    virtual ~State() = default;
    virtual void onEnter() = 0;  // 进入状态时的动作
    virtual void onExit() = 0;   // 离开状态时的动作
    virtual void handleEvent(Event event, std::shared_ptr<State>& nextState,int param) = 0;  // 处理事件并返回下一个状态
};

// 前向声明
class IDLE;
class TRANSFERRING;
class SCANNING;
class CAPTURE;
// 定义状态机类
class StateMachine {
public:
    void start(std::shared_ptr<State> initialState);
    void processEvent(Event event,int param);

private:
    std::shared_ptr<State> currentState;
};

// 定义具体的状态类

// TRANSFERRING
class TRANSFERRING : public State {
public:
    explicit TRANSFERRING(TRANSFER param) : param_(param) {}
    void onEnter() override;
    void onExit() override;
    void handleEvent(Event event, std::shared_ptr<State>& nextState,int param) override;
private:
    TRANSFER param_;  // 存储传递的参数
    QTimer timer;
};

// SCANNING
class SCANNING : public QObject, public State {
public:
    void onEnter() override;
    void onExit() override;
    void handleEvent(Event event, std::shared_ptr<State>& nextState,int param) override;
private slots:
    void handleTimeout();
private:    
    QTimer takephoto_timer; 
    int cnt;
};

// IDLE
class IDLE : public State {
public:
    void onEnter() override;
    void onExit() override;
    void handleEvent(Event event, std::shared_ptr<State>& nextState,int param) override;
};

// CAPTURE
class CAPTURE : public State {
public:
    explicit CAPTURE(int param) : param_(param) {}
    void onEnter() override;
    void onExit() override;
    void handleEvent(Event event, std::shared_ptr<State>& nextState,int param) override;
private:
    int param_;  // 存储传递的参数
    QTimer timer;
};

extern StateMachine sm;
extern ImageProcessingThread* IP_thread;
// 具体实现
void StateMachine::start(std::shared_ptr<State> initialState) {
    currentState = initialState;
    if (currentState) {
        currentState->onEnter();
    }
}

void StateMachine::processEvent(Event event,int param=0) {
    if (!currentState) {
        std::cerr << "No current state to process event." << std::endl;
        return;
    }

    std::shared_ptr<State> nextState;
    currentState->handleEvent(event, nextState, param);

    if (nextState && nextState != currentState) {
        currentState->onExit();
        currentState = nextState;
        currentState->onEnter();
    }
}

void IDLE::onEnter() {
    std::cout << "Entering IDLE" << std::endl;
}

void IDLE::onExit() {
    std::cout << "Exiting IDLE" << std::endl;
}

void IDLE::handleEvent(Event event, std::shared_ptr<State>& nextState,int param) {
    switch (event) {
        case Event::START:
            std::cout << "IDLE: Handling START, transitioning to TRANSFERRING" << std::endl;
            nextState = std::make_shared<TRANSFERRING>(TRANSFER::BACKWARD);
            break;
        case Event::CAPTURE_T:
            std::cout << "IDLE: Handling START, transitioning to CAPTURE" << std::endl;
            nextState = std::make_shared<CAPTURE>(1000);
            break;
        default:
            std::cout << "IDLE: Unknown event, staying in IDLE" << std::endl;
            break;
    }
}
void TRANSFERRING::onEnter() {
    std::cout << "Entering LIMITATION_1" << std::endl;
    std::cout << "进入 TRANSFERRING" << std::endl;
    driver.step.enable(1);
    if (param_==TRANSFER::FORWARD){
        driver.step.setdir(1);
        driver.step.setspeed(1000*1000);
    }else if(param_==TRANSFER::BACKWARD){
        driver.step.setdir(0);
        driver.step.setspeed(1000*1000);
    }
    // 启动线程
    QObject::connect(&timer, &QTimer::timeout, [this](){
        // std::cout << "STEP 正在重复执行..." << std::endl;
        if(driver.LitSW_L.getLimitation()&&param_==TRANSFER::BACKWARD){
            std::cout << "获取中断LitSW_L" << std::endl;
            sm.processEvent(Event::LIMITATION_1);  // TRANSFERRING -> IDLE
        }
        if(driver.LitSW_R.getLimitation()&&param_==TRANSFER::FORWARD){
            std::cout << "获取中断LitSW_R" << std::endl;
            sm.processEvent(Event::LIMITATION_2);  // TRANSFERRING -> SCANNING
        }
    });
    timer.start(1);
    std::cout << "进入 jthread" << std::endl;
}

void TRANSFERRING::onExit() {
    std::cout << "Exiting LIMITATION_1" << std::endl;
    driver.step.enable(0);
    timer.stop();
}

void TRANSFERRING::handleEvent(Event event, std::shared_ptr<State>& nextState,int param) {
    switch (event) {
        case Event::LIMITATION_1:
            std::cout << "LIMITATION_1: Handling LIMITATION_1, transitioning to SCANNING" << std::endl;
            nextState = std::make_shared<SCANNING>();
            break;
        case Event::LIMITATION_2:
            std::cout << "LIMITATION_1: Handling LIMITATION_2, transitioning to IDLE" << std::endl;
            nextState = std::make_shared<IDLE>();
            break;
        default:
            std::cout << "LIMITATION_1: Unknown event, staying in LIMITATION_1" << std::endl;
            break;
    }
}
void SCANNING::handleTimeout() {
        driver.servo.setspeed(1500 * 1000);
        IP_thread->CamCTL->set_camera_auto_focus(true);

        std::cout << "SCANNING=" << cnt << std::endl;
        if (cnt > 3) {
            QTimer::singleShot(100, [this]() {
                std::cout << "SCANNING -> TRANSFERRING=" << cnt << std::endl;
                sm.processEvent(Event::SCANNED);  // SCANNING -> TRANSFERRING
            });
        } else {
            // // 创建一个新的单次定时器来处理延时
            // QTimer::singleShot(1000, [this]() {
            //     std::cout << "singleShot(750)=" << cnt << std::endl;
            // });
            QTimer::singleShot(1050, [this]() {
                std::cout << "singleShot(1250)=" << cnt << std::endl;
                driver.servo.setspeed(1800 * 1000);
            });
        }
        cnt++;
    }
void SCANNING::onEnter() {
    std::cout << "Entering SCANNING" << std::endl;
    cnt=0;
    QObject::connect(&takephoto_timer, &QTimer::timeout,this, &SCANNING::handleTimeout);
    handleTimeout();
    takephoto_timer.start(2000);
}

void SCANNING::onExit() {
    std::cout << "Exiting SCANNING" << std::endl;
    takephoto_timer.stop();
}

void SCANNING::handleEvent(Event event, std::shared_ptr<State>& nextState,int param) {
    switch (event) {
        case Event::SCANNED:
            std::cout << "SCANNING: Handling SCANNED, staying in TRANSFERRING" << std::endl;
            nextState = std::make_shared<TRANSFERRING>(TRANSFER::FORWARD);
            break;
        default:
            std::cout << "SCANNING: Unknown event, staying in SCANNING" << std::endl;
            break;
    }
}
extern QSemaphore semaphore_CAPTURE;
void CAPTURE::onEnter() {
    std::cout << "Entering CAPTURE" << std::endl;
    // // 启动线程
    // QObject::connect(&timer, &QTimer::timeout, [this](){
    //     static int counter = 0;
    //     semaphore_CAPTURE.acquire();
    //     QString  filename = "images/extracted_patch_" + QString::number(counter++) + ".jpg";
    //     bool success = w->image.save(filename, "JPG");
    //     QListWidgetItem *item = new QListWidgetItem(filename);
    //     w->ui->listWidget_2->addItem(item);
    //     w->ui->listWidget_2->scrollToBottom();
    //     std::cout << "image "<< counter <<" save ok" << std::endl;
    // });
    // timer.start(param_);

    QObject::connect(&timer, &QTimer::timeout, [this](){
        semaphore_CAPTURE.acquire();
        if(w->image.size().isEmpty()){
            qDebug() << "image isEmpty";
        }else{
            driver.servo.setspeed(1500*1000);
            // 创建一个新的单次定时器来处理延时
            QTimer::singleShot(1000, [this]() {
                IP_thread->CamCTL->set_camera_auto_focus(true);
            });
            QTimer::singleShot(2000, [this]() {
                static int counter = 0;
                QString filename = "images/timedelay_" + QString::number(counter++) + ".jpg";
                bool success = w->image.save(filename, "JPG");

                QListWidgetItem *item = new QListWidgetItem(filename);
                w->ui->listWidget_2->addItem(item);
                w->ui->listWidget_2->scrollToBottom();
                std::cout << "image " << counter << " timedelay save ok" << std::endl;
                driver.servo.setspeed(1800*1000);
            });

            qDebug() << "get photo";
        }
    });
    timer.start(4000);
}

void CAPTURE::onExit() {
    std::cout << "Exiting CAPTURE" << std::endl;
    timer.stop();
}

void CAPTURE::handleEvent(Event event, std::shared_ptr<State>& nextState,int param) {
    switch (event) {
        case Event::CAPTURE_C:
            std::cout << "CAPTURE: Handling CAPTURE_C, staying in CAPTURE_C" << std::endl;
            param_=param;
            // timer.start(param_);
            break;
        case Event::CAPTURE_T:
            std::cout << "CAPTURE: Handling CAPTURE_T, transitioning in IDLE" << std::endl;
            nextState = std::make_shared<IDLE>();
            break;
        default:
            std::cout << "CAPTURE: Unknown event, staying in CAPTURE" << std::endl;
            break;
    }
}
#endif // STATE_MACHINE_HPP